/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package utils;

import java.io.*;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;

import model.Doc;

import database.DBConnector;
import database.DBNames;

import repco.RepCo;
import sparqlclient.SparqlRequest;
import utils.parser.Parser;
import utils.stemmer.Stemmer;

/**
 *
 * @author falxa
 */
public final class Utils 
{
    public static ArrayList<String> parseStopList(String filePath)
    {
        ArrayList<String> words = new ArrayList<>();
        String currentLine = "";
        
        try 
        {
            BufferedReader br = new BufferedReader(new FileReader(filePath));
            try 
            {
                while((currentLine = br.readLine()) != null)
                {
                   words.add(currentLine);
                }
            }
            catch (IOException ex) 
            {
                System.out.println("Impossible de lire une ligne");
            }
            finally
            {
                try {
                    if (br != null) br.close();
                } catch (IOException ex) {
                    System.out.println("Impossible de fermer le fichier");
                }
            }
            
        } catch (FileNotFoundException ex) 
        {
            System.out.println("Impossible de lire le fichier "+filePath);
        }
        
        return words;
    }
    
    public static void parseFolderContent(File directory, RepCo rc)
    {
        if (directory.isDirectory())
        {
            File[] files = directory.listFiles();
            Arrays.sort(files);
            for (int i=0; i<files.length; i++)
            {
                if (files[i].getName().endsWith(".xml"))
                {
                    Parser.parseFile(files[i], rc);
                }
            }
        }
    }
    
    public static HashMap<Integer, ArrayList<String>> parseQrel(String filename, DBConnector dc)
    {
    	ArrayList<String> xpaths;
    	HashMap<String, ArrayList<String>> docN = new HashMap<>();
    	HashMap<Integer, ArrayList<String>> docData = new HashMap<>();
    	
    	String strLine = null;
    	
    	try{
    		  FileInputStream fstream = new FileInputStream("ressources/qrel/"+filename);
    		  DataInputStream in = new DataInputStream(fstream);
    		  BufferedReader br = new BufferedReader(new InputStreamReader(in));
    		  String[] split;
    		  
    		  //Read File Line By Line
    		  while ((strLine = br.readLine()) != null)   
    		  {
	    		  // Print the content on the console
	    		  split = strLine.split("( |\t)+");
	    		  
	    		  String docname = split[0].replaceAll("Collection/", "");
	    		  String xpath = split[1];
	    		  int isRelevant = Integer.parseInt(split[2]);
	    		  
	    		  if (isRelevant == 1)
	    		  {
	    			  if (docN.containsKey(docname))
	    				  xpaths = docN.get(docname);
	    			  else
	    				  xpaths = new ArrayList<>();
	    			  xpaths.add(xpath);
	    			  docN.put(docname, xpaths);
	    		  }
    		  }
    		  
    		  StringBuilder docRequest = new StringBuilder("select * from " + DBNames.DOCUMENT + " where " + DBNames.DOC_NAME + " IN ");
    		  docRequest.append(Utils.listToIn(docN.keySet())); docRequest.append(";");
  			  ResultSet rsDoc = dc.executeQuery(docRequest.toString());
  			  Doc doc;
  			  if (rsDoc.first())
  			  {
  				  while (!rsDoc.isAfterLast())
  				  {
  					  doc = new Doc(rsDoc);
  					  docData.put(doc.getID(), docN.get(doc.getName()));
  					  rsDoc.next();
  				  }
  			  }
    		  
    		  // ajout du nombre de documents
    		  
    		  //Close the input stream
    		  in.close();
		  }catch (Exception e){//Catch exception if any
			  System.err.println("Error: " + e.getMessage());
			  System.out.println(strLine);
			  e.printStackTrace();
		  }
    	
    	return docData;
    }
    
	
	/**
	 * Parse la requete en entree (parsing, stoplisting, stemming)
	 * 
	 * @param request
	 * @return ArrayList de Term
	 */
	public static ArrayList<String> parseRequest(String request)
	{
		ArrayList<String> terms = new ArrayList<>();
		String words[];
		Stemmer stem = new Stemmer();
		ArrayList<String> stoplist = Utils.parseStopList("ressources/stopliste.txt");

		request = request.replaceAll("(\\p{Punct}|[^(\\p{L}|\\p{N})|œ|Œ])+", " ");

		words = request.split(" +");

		for (int i = 0; i < words.length; i++)
		{
			if ((!stoplist.contains(words[i])) && (words[i].length() > 1))
			{
				words[i] = words[i].toLowerCase();
				/* get term stem */
				terms.add(stem.getStem(words[i]));
			}
		}

		return terms;
	}
	
	public static ArrayList<String> parseRequestSimple(String request)
	{
		ArrayList<String> rq = new ArrayList<>();
		String[] srq = request.split(" ");
		for (String s: srq)
			rq.add(s);
		return rq;
	}
    
    public static String listToIn(Collection list)
    {
    	StringBuilder sb = new StringBuilder("(");
    	for (Object s: list)
    		sb.append("\""+s+"\",");
    	sb.deleteCharAt(sb.length()-1);
    	sb.append(")");
    	return sb.toString();
    }
    
    private static ArrayList<ArrayList<String>> combine(String p, ArrayList<ArrayList<String>> f)
    {
    	ArrayList<ArrayList<String>> as = new ArrayList<>();
    	ArrayList<String> np;
    	
    	if (f.size() == 0)
    	{
    		np = new ArrayList<>();
    		np.add(p);
    		as.add(np);
    	}
    	else
    	{
    		for (ArrayList<String> s : f)
	    	{
    			np = new ArrayList<>();
	    		np.add(p); 
	    		np.addAll(s);
	    		as.add(np);
	    	}
    	}
    	
    	return as;
    }
    
    public static ArrayList<ArrayList<String>> recCombine(List<String> req, SparqlRequest sr)
    {
    	ArrayList<ArrayList<String>> as = new ArrayList<>();
    	
    	if (req.size() > 0)
    	{
	    	// gen synonyms
	    	ArrayList<String> syns = new ArrayList<>();
	    	syns.add(req.get(0));
	    	syns.addAll(sr.getSynonym(req.get(0)));
	    	//syns.addAll(sr.getInstance(req.get(0)));
	    	//syns.addAll(sr.getSubClass(req.get(0)));
	    	
	    	for (String syn: syns)
	    		as.addAll(combine(syn, recCombine(req.subList(1, req.size()), sr)));
    	}
    	
    	return as;
    }
    
    
}
